/**
 * 时间：2024年10月14日 09点10分
 * 缓冲区分析工具
 * 缓冲区分析是指以点、线、面实体为基础，自动建立一定宽度范围的缓冲区多边形图层
 * 然后建立该图层与目标图层的叠加部分，并进行分析而得到所需结果。
 * 她是用来解决邻近度问题的空间分析工具之一。
 */

import * as Cesium from "cesium";
import * as turf from '@turf/turf'
import DrawPolylineUtils from "./DrawPolyLine.js";

/** 线的累计缓冲区坐标 */
let linePositionList = [];
/** 面的累计缓冲区坐标 */
let polygonPositionList = [];

let allEntitiesList = [];

/**
 * @description 格式转换，将点数据拆分、合并成一个大数组
 * @param points
 * @returns {*[]}
 */
function pointsFormatConv(points) {
  let degreesArray = [];
  points.forEach(point => {
    degreesArray.push(point[0]);
    degreesArray.push(point[1]);
  });
  return degreesArray;
}


/**
 * 添加缓冲区
 * @param positions 定位
 * @param viewer cesium初始化视图
 */
function addBuffer(positions, viewer) {
  //向视图添加要素
  const newEntities=viewer.entities.add({
    polygon: {
      hierarchy: new Cesium.PolygonHierarchy(positions),
      material: Cesium.Color.RED.withAlpha(.7),
    }
  });
  allEntitiesList.push(newEntities);
}

/**
 * @description 添加点
 * @param point
 * @param viewer cesium初始化视图
 */
function addPoint(point, viewer) {
  console.log(57, point);
  const newEntities=viewer.entities.add({
    position: Cesium.Cartesian3.fromDegrees(point[0], point[1]),
    point: {
      pixelSize: 10,
      heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
      color: Cesium.Color.RED
    }
  });
  allEntitiesList.push(newEntities);
}

/**
 * @description 添加点缓冲区, 用于初始化
 * @param viewer
 * @param cesiumHandler
 * @param range
 */
export function initPointBuffer(viewer, cesiumHandler, range) {
  //创建画线工具类
  // const drawPolylineUtils = new DrawPolylineUtils({viewer, Cesium,cesiumHandler});
  // //开始画线
  // drawPolylineUtils.startCreate();
  // console.log(67, drawPolylineUtils.getEntitiesPoint());
  let point = [114.40086, 30.51888];
  cesiumHandler.setInputAction(function (event) {
    // 获取点击位置的射线
    const ray = viewer.camera.getPickRay(event.position);
    // 使用射线在地球表面找到鼠标点击位置
    const earthPosition = viewer.scene.globe.pick(ray, viewer.scene);
    // 如果点击到地球表面
    if (Cesium.defined(earthPosition)) {
      // 将 Cartesian3 转换为经纬度
      const cartographic = Cesium.Cartographic.fromCartesian(earthPosition);
      // 将弧度转换为度
      const longitude = Cesium.Math.toDegrees(cartographic.longitude);
      const latitude = Cesium.Math.toDegrees(cartographic.latitude);
      addPoint([longitude, latitude], viewer);
      const pointF = turf.point([longitude, latitude]);
      const buffered = turf.buffer(pointF, range, {units: "meters"});
      const coordinates = buffered.geometry.coordinates;
      const points = coordinates[0];
      const degreesArray = pointsFormatConv(points);
      addBuffer(Cesium.Cartesian3.fromDegreesArray(degreesArray), viewer);
    }
    // 移除 LEFT_DOWN 事件处理程序
    cesiumHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOWN);
  }, Cesium.ScreenSpaceEventType.LEFT_DOWN);

  // cesiumHandler.setInputAction(function () {
  //
  // },Cesium.ScreenSpaceEventType.LEFT_DOWN);
}

/**
 * @description 添加线
 * @param positions 定位
 * @param viewer 视图
 */
function addPolyline(positions, viewer) {
  const newEntities=viewer.entities.add({
    polyline: {
      positions: Cesium.Cartesian3.fromDegreesArray(positions),
      width: 2,
      material: Cesium.Color.BLUE,
      clampToGround: true
    }
  });
  allEntitiesList.push(newEntities);
}

/**
 * @description 初始化 线 缓冲区
 * @param viewer
 * @param cesiumHandler
 */
export function initPolylineBuffer(viewer, cesiumHandler, range) {
  let _polyline = null; //活动线
  let _polylineLast = null; //最后一条线
  let _positions = [];  //活动点
  let _positionJWDList = [];  //活动点,经纬度
  let _entities_point = [];  //脏数据
  let _entities_line = [];  //脏数据
  let _polylineData = null; //用于构造线数据
  cesiumHandler.setInputAction(function (evt) { //单机开始绘制
    //屏幕坐标转地形上坐标
    var cartesian = getCatesian3FromPX(viewer, evt.position);
    if (_positions.length == 0) {
      _positions.push(cartesian.clone());
    }

    _positions.push(cartesian);
    const point = viewer.entities.add({
      position: cartesian,
      point: {
        pixelSize: 10,
        color: Cesium.Color.YELLOW,
      }
    });
    allEntitiesList.push(point);
    _entities_point.push(point);
    // 获取点的世界坐标
    const start_point = viewer.scene.camera.pickEllipsoid(evt.position, viewer.scene.globe.ellipsoid);
    if (start_point) {
      //将笛卡尔三维坐标转为地图坐标（弧度）
      const cartographic = viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian);
      //将地图坐标（弧度）转为十进制的度数
      const lat_String = Cesium.Math.toDegrees(cartographic.latitude).toFixed(4);
      const log_String = Cesium.Math.toDegrees(cartographic.longitude).toFixed(4);
      _positionJWDList.push([parseFloat(log_String), parseFloat(lat_String)]);
    }
  }, Cesium.ScreenSpaceEventType.LEFT_DOWN);

  cesiumHandler.setInputAction(function (evt) { //移动时绘制线
    if (_positions.length < 1) return;
    var cartesian = getCatesian3FromPX(viewer, evt.endPosition);
    if (!Cesium.defined(_polyline)) {
      _polyline = viewer.entities.add({
        polyline: {
          //使用cesium的peoperty
          positions: new Cesium.CallbackProperty(function () {
            return _positions
          }, false),
          show: true,
          material: Cesium.Color.RED,
          width: 3,
          clampToGround: true
        }
      });
      allEntitiesList.push(_polyline);
      _entities_line.push(_polyline);
    }
    if (_polyline) {
      _positions.pop();
      _positions.push(cartesian);
    }
  }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

  //取消绘画事件,注意,不再是销毁
  // this.destroy();
  cesiumHandler.setInputAction((evt) => {
    cesiumHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOWN);
    cesiumHandler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK);
    cesiumHandler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
    cesiumHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);

    console.log(126, _positionJWDList);
    linePositionList.push(_positionJWDList);
    let degreesArray = pointsFormatConv(_positionJWDList);
    addPolyline(degreesArray, viewer);
    //创建线要素
    const polylineF = turf.lineString(_positionJWDList);
    //创建缓冲区
    const buffered = turf.buffer(polylineF, range, {units: "meters"});
    const coordinates = buffered.geometry.coordinates;
    _positionJWDList = coordinates[0];
    degreesArray = pointsFormatConv(_positionJWDList);
    addBuffer(Cesium.Cartesian3.fromDegreesArray(degreesArray), viewer);
  }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
  // let degreesArray = pointsFormatConv(points);
  // addPolyline(degreesArray, viewer);
  // //创建线要素
  // const polylineF = turf.lineString(points);
  // //创建缓冲区
  // const buffered = turf.buffer(polylineF, 30, {units: "meters"});
  // const coordinates = buffered.geometry.coordinates;
  // points = coordinates[0];
  // degreesArray = pointsFormatConv(points);
  // addBuffer(Cesium.Cartesian3.fromDegreesArray(degreesArray), viewer);
}

/**
 * @description 更新缓冲图层
 * @param viewer
 * @param radius 范围大小
 */
export function updatePolylineBuffer(viewer, radius) {
  //复原,这里linePositionList是一个二维数组
  linePositionList.forEach((linePosition) => {
    let _positionJWDList = linePosition;
    let degreesArray = pointsFormatConv(_positionJWDList);
    addPolyline(degreesArray, viewer);
    //创建线要素
    const polylineF = turf.lineString(_positionJWDList);
    //创建缓冲区
    const buffered = turf.buffer(polylineF, radius, {units: "meters"});
    const coordinates = buffered.geometry.coordinates;
    _positionJWDList = coordinates[0];
    degreesArray = pointsFormatConv(_positionJWDList);
    addBuffer(Cesium.Cartesian3.fromDegreesArray(degreesArray), viewer);
  });
}


/**
 * @description 添加面
 * @param positions
 * @param viewer
 */
function addPolygon(positions, viewer) {
  const newEntities=viewer.entities.add({
    polygon: {
      hierarchy: new Cesium.PolygonHierarchy(positions),
      material: Cesium.Color.BLUE.withAlpha(.6)
    }
  });
  allEntitiesList.push(newEntities);
}

/**
 * @description 添加面缓冲区
 * @param viewer
 * @param pointList
 * @param range
 */
export function initPolygonBuffer(viewer, pointList, range) {
  let points = [
    [114.3940, 30.5220],
    [114.3970, 30.5220],
    [114.3980, 30.5240],
    [114.3960, 30.5250],
    [114.3940, 30.5220],
  ];
  //这里的第一个位置和最后一个位置不一致，所以我们手动解决，
  //当然，这里肯定不是最优解，所以在后期还需要进行修改
  pointList[pointList.length - 1] = pointList[0];
  console.log(248, pointList);
  //添加到记录中
  polygonPositionList.push(pointList);
  let degreesArray = pointsFormatConv(pointList);
  addPolygon(Cesium.Cartesian3.fromDegreesArray(degreesArray), viewer);
  //创建面要素
  const polylineF = turf.polygon([pointList]);
  const buffered = turf.buffer(polylineF, range, {units: "meters"});
  const coordinates = buffered.geometry.coordinates;
  pointList = coordinates[0];
  degreesArray = pointsFormatConv(pointList);
  addBuffer(Cesium.Cartesian3.fromDegreesArray(degreesArray), viewer);
}

/**
 * @description 更新面缓冲区
 * @param viewer
 * @param radius
 */
export function updatePolygonBuffer(viewer, radius) {
  console.log(266, polygonPositionList);
  //遍历
  polygonPositionList.forEach((item) => {
    let _positionJWDList = item;
    let degreesArray = pointsFormatConv(_positionJWDList);
    addPolyline(degreesArray, viewer);
    //创建线要素
    const polylineF = turf.lineString(_positionJWDList);
    //创建缓冲区
    const buffered = turf.buffer(polylineF, radius, {units: "meters"});
    const coordinates = buffered.geometry.coordinates;
    _positionJWDList = coordinates[0];
    degreesArray = pointsFormatConv(_positionJWDList);
    addBuffer(Cesium.Cartesian3.fromDegreesArray(degreesArray), viewer);
  });
  // const start_point = viewer.scene.camera.pickEllipsoid(evt.position, $this.viewer.scene.globe.ellipsoid);
  // if (start_point) {
  //   //将笛卡尔三维坐标转为地图坐标（弧度）
  //   const cartographic = viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian);
  //   //将地图坐标（弧度）转为十进制的度数
  //   const lat_String = Cesium.Math.toDegrees(cartographic.latitude).toFixed(4);
  //   const log_String = Cesium.Math.toDegrees(cartographic.longitude).toFixed(4);
  //   _positionsJWDList.push([parseFloat(log_String), parseFloat(lat_String)]);
  // }
}


function getCatesian3FromPX(viewer, px) {
  var cartesian;
  var ray = viewer.camera.getPickRay(px);
  if (!ray) return null;
  cartesian = viewer.scene.globe.pick(ray, viewer.scene);
  return cartesian;
}

/**
 * @description 清空
 * @param viewer
 */
export function clearAllEntitiesList(viewer){
  allEntitiesList.forEach(item => {
    viewer.entities.remove(item);
  });
  allEntitiesList=[];
}
